package com.yuanlrc.base.service.admin;

import com.yuanlrc.base.bean.PageBean;
import com.yuanlrc.base.dao.admin.BookDao;
import com.yuanlrc.base.dao.admin.BorrowDao;
import com.yuanlrc.base.dao.admin.StudentDao;
import com.yuanlrc.base.dao.admin.ViolationDao;
import com.yuanlrc.base.entity.admin.*;
import com.yuanlrc.base.util.SessionUtil;
import org.apache.commons.codec.language.bm.Lang;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import sun.dc.pr.PRError;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.Date;
import java.util.List;

import static com.yuanlrc.base.entity.admin.Book.BOOK_ACTIVE;

@Service
@Transactional
public class BorrowService {

    @Autowired
    private BorrowDao borrowDao;
    @Autowired
    private BookDao bookDao;
    @Autowired
    private StudentDao studentDao;
    @Autowired
    private ViolationDao violationDao;


    public List<Borrow> findAll() {
        return borrowDao.findAll();
    }
    public Borrow find(Long id){
        return borrowDao.find(id);
    }

    /**
     * 分页查找借阅列表
     *
     * @param borrow
     * @param pageBean
     * @return
     */
    public PageBean<Borrow> findByName(Borrow borrow, PageBean<Borrow> pageBean) {
        ExampleMatcher withMatcher = ExampleMatcher.matching().withMatcher("bookName", ExampleMatcher.GenericPropertyMatchers.contains());
        withMatcher = withMatcher.withIgnorePaths("status");
        Example<Borrow> example = Example.of(borrow, withMatcher);
        Pageable pageable = PageRequest.of(pageBean.getCurrentPage() - 1, pageBean.getPageSize());
        Page<Borrow> findAll = borrowDao.findAll(example, pageable);
        for (Borrow borrow1 : findAll) {
            borrow1.setBookName(borrow1.getBook().getBookName());
            borrow1.setStudentName(borrow1.getStudent().getStudentName());
        }
        for (Borrow borrow1 : findAll) {
            if (borrow1.getReturnTime() == null) {
                if (new Date().getTime()>borrow1.getExpectedReturnTime().getTime() && borrow1.getOverTime() == 0) {
                    borrow1.setOverTime(1);
                    Violation violation = new Violation();
                    violation.setStudent(borrow1.getStudent());
                    violation.setBook(borrow1.getBook());
                    violation.setBorrow(borrow1);
                    violation.setReasonsForViolation("归还逾期");
                    violationDao.save(violation);
                }
            }
        }
        pageBean.setContent(findAll.getContent());
        pageBean.setTotal(findAll.getTotalElements());
        pageBean.setTotalPage(findAll.getTotalPages());
        return pageBean;
    }


    /**
     * 图书归还功能
     *
     * @param id
     * @return
     */
    public boolean returnBook(Long id) {
        //借阅记录对象
        Borrow borrow = borrowDao.find(id);

        Student loginedStudent = SessionUtil.getLoginedStudent();
        if(loginedStudent != null){
            //若一条记录状态为已逾期 return false
            if (borrow.getOverTime()==1){
                return false;
            }
        }
        //若一条记录状态为已归还 return false
        if (borrow.getBorrowState()==1){
            return false;
        }
        //通过id查询到借阅这本书的学生
        Student student = studentDao.find(borrow.getStudent().getId());
        //通过id查询对应的图书
        Book book = bookDao.find(borrow.getBook().getId());
        //将库存增加 增加数量为归还的数量
        book.setCannum(book.getCannum() + borrow.getBorrowNum());
        //将借出数量减少 减少数量为归还的数量
        book.setNum(book.getNum() - borrow.getBorrowNum());
        book.setState(BOOK_ACTIVE);
        //将借阅数量归零
        borrow.setBorrowNum(0);
        //状态设置为已归还
        borrow.setBorrowState(1);
        //设置归还时间
        borrow.setReturnTime(new Date());
        if (borrow.getReturnTime()!=null){
            if (borrow.getExpectedReturnTime().getTime()>borrow.getReturnTime().getTime()){
                borrow.setOverTime(0);
            }
        }
        return true;
    }

    /**
     * 定时器定时执行
     * 添加逾期记录
     */
    public void addRecord() {
        List<Borrow> all = borrowDao.findAll();
        for (Borrow borrow1 : all) {
            if (borrow1.getReturnTime() == null) {
                if (new Date().getTime()>borrow1.getExpectedReturnTime().getTime() && borrow1.getOverTime() == 0) {
                    borrow1.setOverTime(1);
                    Violation violation = new Violation();
                    violation.setStudent(borrow1.getStudent());
                    violation.setBook(borrow1.getBook());
                    violation.setBorrow(borrow1);
                    violation.setReasonsForViolation("归还逾期");
                    violationDao.save(violation);
                }
            }
        }
    }

    public Borrow save(Borrow borrow) {
        return borrowDao.save(borrow);
    }

    public List<Borrow> findByStudentId(Long studentId) {
        return borrowDao.findByStudentId(studentId);
    }

    /**
     * 搜索分类列表
     * @param pageBean
     * @param borrow
     * @return
     */
    public PageBean<Borrow> findList(PageBean<Borrow> pageBean,Borrow borrow,Long id){

        Specification<Borrow> specification = new Specification<Borrow>() {
            /**
             *
             */
            private static final long serialVersionUID = 1L;
            @Override
            public Predicate toPredicate(Root<Borrow> root,
                                         CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                Predicate predicate = null;
                Predicate equal1 = criteriaBuilder.equal(root.get("student"), id);
                predicate = criteriaBuilder.and(equal1);
                return predicate;
            }
        };
        Sort sort = Sort.by(Sort.Direction.DESC,"borrowTime");
        PageRequest pageable = PageRequest.of(pageBean.getCurrentPage()-1, pageBean.getPageSize(), sort);
        Page<Borrow> findAll = borrowDao.findAll(specification, pageable);
        pageBean.setContent(findAll.getContent());
        pageBean.setTotal(findAll.getTotalElements());
        pageBean.setTotalPage(findAll.getTotalPages());
        return pageBean;
    }

}
